package com.hu.common.util.excel;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.StrUtil;
import com.hu.common.util.adm.WebUtil;
import com.hu.common.util.excel.kit.ExcelSheetData;
import com.hu.common.util.response.Result;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

/**
 * @author 00351634
 * @version 1.0
 * @date 2024/12/24 13:40
 * @description: 导入导出工具类
 */
public class FoxExcel {

    /**
     * 默认导入成功response
     */
    private static final Supplier DEFAULT_SUCCESS = () -> {
        Result<Void> success = Result.success();
        success.setMessage("导入成功");
        return success;
    };

    /**
     * 从MultipartFile文件中读取数据，并根据提供的Sheet定义类导入数据。 如果存在错误数据，则将其导出到名为"异常-<原始文件名>"的Excel文件中，并返回成功响应。
     *
     * @param file 文件对象，MultipartFile类型
     * @param sheetDefinition Sheet定义类数组，用于指定每个Sheet的类定义
     */
    public static void read(MultipartFile file, Class... sheetDefinition) {
        read(file, null, DEFAULT_SUCCESS, sheetDefinition);

    }

    /**
     * 从MultipartFile文件中读取数据，并根据提供的Sheet定义类导入数据。 如果存在错误数据，则将其导出到指定的错误Excel文件中，并返回成功响应。
     *
     * @param file 文件对象，MultipartFile类型
     * @param errorExcelName 错误Excel文件的名称，如果为null或空字符串，则使用默认名称"异常-<原始文件名>"
     * @param sheetDefinition Sheet定义类数组，用于指定每个Sheet的类定义
     */
    public static void read(MultipartFile file, String errorExcelName, Class... sheetDefinition) {
        read(file, errorExcelName, DEFAULT_SUCCESS, sheetDefinition);
    }

    /**
     * 从MultipartFile文件中读取数据，并根据提供的Sheet定义类导入数据。 如果存在错误数据，则将其导出到指定的错误Excel文件中，并返回由success参数指定的成功响应。
     *
     * @param file 文件对象，MultipartFile类型
     * @param errorExcelName 错误Excel文件的名称，如果为null或空字符串，则使用默认名称"异常-<原始文件名>"
     * @param success 成功时返回的响应数据提供者
     * @param sheetDefinition Sheet定义类数组，用于指定每个Sheet的类定义
     */
    public static void read(MultipartFile file, String errorExcelName, Supplier success, Class... sheetDefinition) {
        Assert.notEmpty(sheetDefinition);
        ExcelImporter importer = new ExcelImporter(file);
        importer.importData(Arrays.asList(sheetDefinition), WebUtil.getResponse(),
            StrUtil.blankToDefault(errorExcelName, "异常-" + file.getOriginalFilename()), success);
    }

    /**
     * 将数据写入Excel文件并返回给客户端。
     *
     * @param fileName Excel文件的名称
     * @param excelSheetDataPairs 包含Sheet定义类和数据列表的Pair对象数组，用于指定每个Sheet的数据内容
     */
    public static void write(String fileName, Pair<Class, List>... excelSheetDataPairs) {
        Assert.notEmpty(excelSheetDataPairs);
        List<ExcelSheetData> excelSheetDataList = new ArrayList();
        for (Pair pair : excelSheetDataPairs) {
            ExcelSheetData excelSheetData = new ExcelSheetData();
            excelSheetData.setSheetDefinition((Class)pair.getKey());
            excelSheetData.setData(
                Optional.ofNullable(pair.getValue()).map(v -> (List)v).orElseGet(CollectionUtil::newArrayList));
            excelSheetDataList.add(excelSheetData);
        }
        ExcelExporter excelExporter = new ExcelExporter();
        excelExporter.exportData(excelSheetDataList, WebUtil.getResponse(), fileName);
    }
}
